#ifndef     __UART_RECEIVER_H
#define     __UART_RECEIVER_H

#include "./codec.h"

namespace utils {

template <uint32_t BuffCount, uint32_t BufferSize>
struct UartReceiver_t {

public:
    static const uint8_t Head0 = 0xE1;
    static const uint8_t Head1 = 0x1E;
    static const uint8_t End = 0xEF;

    UartReceiver_t() :
        m_head_flag(false),
        m_body_flag(false),
        m_recv_index(0),
        m_buf_index(0)
    {
        m_pbuf = m_recv_buf[m_buf_index];
    }

    void recv_byte(uint8_t byte) {
        if (m_body_flag) {
            recv_body(byte);
            return;
        }

        if (m_head_flag && (byte == Head1)) {
            m_body_flag = true;
            m_head_flag = false;
            m_pbuf[0] = Head0;
            m_pbuf[1] = Head1;
            m_recv_index = 2;
            m_recv_len = 0;
        } else {
            m_head_flag = byte == Head0;
        }
    }

private:
    void recv_body(uint8_t byte) {
        if (m_recv_index >= BufferSize) {
            set_next_buf();
            return;
        }
        
        m_pbuf[m_recv_index] = byte;

        m_recv_index ++;
        if (m_recv_index == 4) {
            m_recv_len = decode_uint16(m_pbuf + 2);
            return;
        }

        if ((byte == End) && (m_recv_index == m_recv_len)) {

        }
    }

    void set_next_buf() {
        m_buf_index ++;
        if (m_buf_index >= BuffCount) {
            m_buf_index = 0;
        }
        m_pbuf = m_recv_buf[m_buf_index];
        m_head_flag = false;
        m_body_flag = false;
        m_recv_index = 0;
        m_recv_len = 0;
    }

private:
    uint8_t m_recv_buf[BuffCount][BufferSize];
    uint8_t *m_pbuf;
    bool m_head_flag;
    bool m_body_flag;
    uint8_t m_buf_index;
    uint8_t m_recv_index;
    uint8_t m_recv_len;
};

}




#endif
